/**
 * The contents of this file are subject to the license and copyright detailed in the LICENSE and NOTICE files at the root of the source tree and available online at
 * http://www.askosi.org/license.html
 */
package be.destin.skos.core;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.log4j.Logger;

import be.destin.beans.Reflector;

abstract class ConnectionPool {

	/** log4j category */
	private static Logger log = Logger.getLogger(ConnectionPool.class);

	String dbURL = null; // URL for connecting to SparQL endpoint
	String dbUsername = null;
	String dbPassword = null;
	String validationQuery = "SELECT ?s ?o ?p WHERE {?s ?o ?p} LIMIT 1";

	int maxConnections = 30;
	int maxWait = 15000; // milliseconds
	int maxIdle = -1;
	
	protected static Map<String,ConnectionPool> openedPools = new HashMap<String,ConnectionPool>();

	public final static String substBeg = "{";
	public final static char substEnd = '}';
	
	public final static char mapKey = '@';

	String name;
	Properties properties;
	Map<String,Map<String,String>> bagParam = new HashMap<String,Map<String,String>>();
	
	ConnectionPool () {
		super();
	}

	public static ConnectionPool getConnectionPool(String name) {
		return openedPools.get(name);
	}

	public void setName(String name) {
		if (name == null) return;
		this.name = name.trim();
		openedPools.put(name,this);
	}
	
	public String getName() {
		return this.name;
	}
	
	public abstract Map<String,String> evalMap(String query);
	
	public String getValue(Object beanToReflect, String nameParam) {
		int pIndir = nameParam.indexOf(mapKey);
		String key = null;
		if (pIndir >= 0) {
			key = nameParam.substring(pIndir+1);
			if (key != null) {
				key = Reflector.substitute(beanToReflect,key,null);
			}
			nameParam = nameParam.substring(0,pIndir);
		}
		String result = null;
		if (key != null) {
			Map<String,String> aMap = bagParam.get(nameParam);
			if (aMap==null) {
				aMap = this.evalMap(properties.getProperty(nameParam));
				bagParam.put(nameParam,aMap);
			}
			if (aMap!=null) {
				result = aMap.get(key); 
			}
		}
		else result = properties.getProperty(nameParam);
		return result;
	}

	/**
	 * This function returns a message with {field with a getter} substituted with information of this entry
	 * return the message
	 */
	public String substitute(Object beanToReflect, String input) {
		if (input == null) return null;
		int fromIndex = 0;
		int i = 0;
		StringBuffer output = new StringBuffer();
		while ( (i = input.indexOf(substBeg, fromIndex)) >= 0 ) {
			output.append(input.substring(fromIndex,i));
			fromIndex = i+1;
			int j = input.indexOf(substEnd, fromIndex);
			if (j > i) {
				String nameParam = input.substring(i+1,j);
				if (nameParam.length() > 0) {
					String result = getValue(beanToReflect, nameParam);
					if (result == null) {
						output.append(substBeg);
						output.append(nameParam);
						output.append(substEnd);
					}
					else {
						output.append(result);
					}
				}
				else {
					output.append(substBeg);
					output.append(substEnd);
				}
				fromIndex = j+1;
			}
			else output.append(substBeg);
		}
		output.append(input.substring(fromIndex));
		return output.toString();
	}
}
